package view.commonview;

import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import view.UtilityConstants;
import model.LogicType;
import model.editormodel.Input;
import model.editormodel.LogicEditorElement;
import model.editormodel.Output;

/**
 * <b>Funktion:</b> Visualisierung der Verbindung zwischen zwei Komponenten<br>
 * <b>In Verbindung stehende Klassen:</b> <code>Input, Output</code><br>
 * <br>
 * View-Klasse die eine Verbindung zwischen zwei Bauteilen repraesentiert. Hat
 * einen Start- und Endpunkt, sowie den zugehoerigen <code>GeneralPath</code>
 * der nur aus horizontalen und vertikalen Linien besteht.
 * 
 * @author Team Locsi
 * 
 */
public class ConnectorPath {

	/*
	 * Input und Output Objekte der Leitung
	 */
	private Input target;
	private Output source;

	/*
	 * GeneralPath, der die Leitung grafisch darstellt
	 */
	private GeneralPath path;

	/*
	 * Liste mit den Ecken des GeneralPath path (wird fuer das 'Zurueckzeichnen'
	 * der Linien vom End zum Startpunkt benoetigt, da diese sonst mit einer
	 * 'Luftlinie' verbunden werden wuerden)
	 */
	private List<Point2D> cornersOfPath;

	/*
	 * Variable die angibt ob die Leitung markiert ist oder nicht
	 */
	private boolean isMarked;

	/*
	 * Punkt-Objekte fuer Start- und Endpunkt
	 */
	private Point2D startPoint;
	private Point2D targetPoint;

	/**
	 * Dieser Konstruktor erzeugt ein <code>ConnectorPath</code>-Objekt.
	 * 
	 * @param source
	 *            <code>Output</code> - Referenz zum Startpunkt der Verbindung
	 * @param target
	 *            <code>Input</code> - Referenz zum Endpunkt der Verbindung
	 */
	public ConnectorPath(Output source, Input target) {
		this.source = source;
		this.target = target;
		this.path = new GeneralPath();
		this.cornersOfPath = new ArrayList<Point2D>();
	}

	/**
	 * Setzt den Endpunkt der Verbindung.
	 * 
	 * @param target
	 *            <code>Input</code> - Referenz auf den <code>Input</code>
	 * @throws IllegalArgumentException
	 *             - falls kein <code>Input</code>-Objekt uebergeben wurde
	 *             sondern z.B. ein <code>Output</code>
	 */
	public void setTarget(Input target) throws IllegalArgumentException {
		this.target = target;
	}

	/**
	 * Gibt den Endpunkt der Verbindung zurueck.
	 * 
	 * @return <code>Input</code> - den Endpunkt der Verbindung
	 */
	public Input getTarget() {
		return target;
	}

	/**
	 * Setzt den Startpunkt der Verbindung.
	 * 
	 * @param source
	 *            <code>Output</code> - Referenz auf den <code>Output</code>
	 * @throws IllegalArgumentException
	 *             - falls kein <code>Input</code>-Objekt uebergeben wurde
	 *             sondern z.B. ein <code>Output</code>
	 */
	public void setSource(Output source) throws IllegalArgumentException {
		this.source = source;
	}

	/**
	 * Gibt den Startpunkt der Verbindung zurueck.
	 * 
	 * @return <code>Output</code> den Startpunkt der Verbindung
	 */
	public Output getSource() {
		return source;
	}

	/**
	 * Setzt die Markierung des <code>ConnectorPath</code> auf den uebergeben
	 * Wert.
	 * 
	 * @param isMarked
	 *            <code>boolean</code> - <code>true</code>, falls markiert;
	 *            <code>false</code> sonst
	 */
	public void setMarked(boolean isMarked) {
		this.isMarked = isMarked;
	}

	/**
	 * Gibt den Wert der Markierung zurueck.
	 * 
	 * @return <code>boolean</code> - <code>true</code>, falls markiert;
	 *         <code>false</code> sonst
	 */
	public boolean isMarked() {
		return isMarked;
	}

	/**
	 * Gibt den <code>GeneralPath<code> des <code>ConnectorPath</code> zurueck.
	 * 
	 * @return <code>GeneralPath</code> - den <code>GeneralPath</code>
	 */
	public GeneralPath getPath() {
		return path;
	}

	/**
	 * Diese Methode bekommt die aktuellen Anfangs- und Endkoordinaten des
	 * <code>GeneralPath</code> uebergeben und berechnet diesen mit Hilfe der
	 * Methode calcPath.
	 */
	public void setPath(Point2D start, Point2D end) {
		calcPath(start, end);
	}

	/**
	 * Diese Methode holt sich die aktuellen Koordinaten von dem zugehoerigen
	 * Input und Output und berechnet mit Hilfe der Methode calcPath den
	 * <code>GeneralPath</code> neu
	 */
	public void updatePath() {
		double sourceXtoSet = 0;
		double sourceYtoSet = 0;
		double targetXtoSet = 0;
		double targetYtoSet = 0;

		sourceXtoSet = source.getXRelToElement();
		sourceYtoSet = source.getYRelToElement();

		targetXtoSet = target.getXRelToElement();
		targetYtoSet = target.getYRelToElement();

		startPoint = new Point2D.Double(sourceXtoSet
				+ source.getMySuperElement().getXCoord()
				+ ((double) UtilityConstants.IO_RADIUS) / 2, sourceYtoSet
				+ source.getMySuperElement().getYCoord()
				+ ((double) UtilityConstants.IO_RADIUS) / 2);
		targetPoint = new Point2D.Double(targetXtoSet
				+ target.getMySuperElement().getXCoord()
				+ ((double) UtilityConstants.IO_RADIUS) / 2, targetYtoSet
				+ target.getMySuperElement().getYCoord()
				+ ((double) UtilityConstants.IO_RADIUS) / 2);
		calcPath(startPoint, targetPoint);
	}

	/**
	 * Hilfsmethode, die einen gezeichneten Pfad von hinten nach vorne
	 * durchlaeuft. Wichtig, da sonst der Paths automatisch geschlossen wird und
	 * somit Linien falsch angeklickt werden koennen. Wird sofort nach jedem
	 * Verbindung zeichnen aufgerufen
	 * 
	 * @param list
	 *            Liste der Eckpunkte der gerade gezeichneten Verbindung
	 */
	private void goBackDrawedPath(List<Point2D> list) {
		for (int i = list.size() - 1; i >= 0; i--) {
			path.lineTo(list.get(i).getX(), list.get(i).getY());
		}
		list.clear();
	}

	/**
	 * Hilfsmethode zum Berechnen des <code>GeneralPath</code> mit
	 * 
	 * @param start
	 *            als Anfangspunkt
	 * @param end
	 *            als Endpunkt
	 */
	private void calcPath(Point2D start, Point2D end) {
		path.reset();
		// intelligentes Zeichnen der Linien
		// ist der x-wert des inputs um mehr als 20 groesser als der des outputs
		// wird linie entsprechend gezeichnet
		if (start.getX() < end.getX() && end.getX() - start.getX() > 20) {
			if (target != null && source != null) {
				LogicType targetType = target.getMySuperElement().getType();
				LogicType sourceType = source.getMySuperElement().getType();
				// input
				switch (targetType) {

				case TWO_MX:

					// output
					switch (sourceType) {

					case TWO_MX:
						// von 2mx zu 2mx
						intelligentTwoMxToTwoMxStartXSmallerThanEndX(start, end);

						break;

					case FLIPFLOP:
						// von ff zu 2mx
						intelligentFFToTwoMxStartXSmallerThanEndX(start, end);
						break;

					case NODE:
						intelligentNodeToTwoMxStartXSmallerThanEndX(start, end);
						break;

					default:
						// von default zu 2mx
						intelligentDefaultToTwoMxStartXSmallerThanEndX(start,
								end);
						break;
					}
					break;

				case FLIPFLOP:

					switch (sourceType) {

					case TWO_MX:
						intelligentTwoMxToFFStartXSmallerEndX(start, end);
						break;

					case FLIPFLOP:
						unIntelligentDefaultToDefaultStartXSmallerThanEndX(
								start, end);
						break;

					case NODE:
						intelligenteNodeToDefaultStartXSmallerThanEndX(start,
								end);
						break;

					default:
						unIntelligentDefaultToDefaultStartXSmallerThanEndX(
								start, end);
						break;
					}
					break;

				default:

					switch (sourceType) {

					case TWO_MX:
						intelligentTwoMxToDefaultStartXSmallerThanEndX(start,
								end);
						break;

					case FLIPFLOP:
						intelligentFFToDefaultStartXSmallerThanEndX(start, end);
						break;

					case NODE:
						intelligenteNodeToDefaultStartXSmallerThanEndX(start,
								end);
						break;

					default:
						unIntelligentDefaultToDefaultStartXSmallerThanEndX(
								start, end);
						break;
					}
					break;
				}
			} else {
				unIntelligentDefaultToDefaultStartXSmallerThanEndX(start, end);
			}
			// ist der x-wert des inputs groesser als der des outputs aber um
			// nicht mehr als 20, wird linie entsprechend gezeichnet
		} else if (start.getX() < end.getX() && end.getX() - start.getX() <= 20) {
			// linie kann erst intelligent gezeichnet werden, wenn sie fest
			// an einem input und output gesetzt ist
			if (target != null && source != null) {
				LogicType targetType = target.getMySuperElement().getType();
				LogicType sourceType = source.getMySuperElement().getType();

				// input
				switch (targetType) {

				case TWO_MX:
					// output
					switch (sourceType) {

					case TWO_MX:
						intelligentTwoMxToTwoMxStartXSmallerThanEndX(start, end);
						break;

					case FLIPFLOP:
						intelligentFFToTwoMxStartXSmallerThanEndX(start, end);
						break;

					case NODE:
						intelligentNodeToTwoMxStartXSmallerThanEndX(start, end);
						break;

					default:
						intelligentDefaultToTwoMxStartXSmallerThanEndX(start,
								end);
						break;
					}

					break;

				case FLIPFLOP:

					switch (sourceType) {

					case TWO_MX:
						intelligentTwoMxToFFStartXSmallerEndX(start, end);
						break;

					case FLIPFLOP:
						unIntelligentDefaultToDefaultStartXSmallerThanEndX(
								start, end);
						break;

					case NODE:
						intelligenteNodeToDefaultStartXSmallerThanEndX(start,
								end);
						break;

					default:
						unIntelligentDefaultToDefaultStartXSmallerThanEndX(
								start, end);
						break;
					}
					break;

				default:

					switch (sourceType) {

					case TWO_MX:
						intelligentTwoMxToDefaultStartXSmallerThanEndX(start,
								end);
						break;

					case FLIPFLOP:
						intelligentDefaultToDefaultStartXLittleSmallerThanEndX(
								start, end);
						break;

					case NODE:
						intelligenteNodeToDefaultStartXSmallerThanEndX(start,
								end);
						break;

					default:
						intelligentDefaultToDefaultStartXLittleSmallerThanEndX(
								start, end);

						break;
					}
				}
				// ist dies noch nicht der fall, wird sie nicht intelligent
				// gezeichnet
			} else {
				unIntelligentDefaultToDefaultStartXSmallerThanEndX(start, end);
			}

			// ist der x-wert des startpunktes groesser als der des endpunktes,
			// wird die linie entsprechend gezeichnet
		} else if (start.getX() >= end.getX()) {
			// ist die linie bereits festgesetzt durch einen input und output,
			// wird diese intelligent gezeichnet
			if (target != null && source != null) {
				LogicType targetType = target.getMySuperElement().getType();
				LogicType sourceType = source.getMySuperElement().getType();

				// input
				switch (targetType) {

				case TWO_MX:
					// output
					switch (sourceType) {

					case TWO_MX:
						// 2mx zu 2mx
						intelligentTwoMxToTwoMxStartXgreaterThanEndX(start, end);
						break;

					case FLIPFLOP:
						intelligentFFToTwoMxStartXgreaterThanEndX(start, end);
						break;

					case NODE:
						intelligentNodeToTwoMxStartXgreaterThanEndX(start, end);
						break;

					case SELFDEFINED:
						intelligentSelfDefinedToTwoMxStartXgreaterThandEndX(
								start, end);
						break;

					default:
						intelligentDefaultToTwoMxStartXgreaterThanEndX(start,
								end);
						break;
					}

					break;

				case SELFDEFINED:

					switch (sourceType) {

					case TWO_MX:
						intelligentTwoMxToSelfDefined(start, end);
						break;

					case FLIPFLOP:
						intelligentFlipFlopToSelfDefined(start, end);
						break;

					case NODE:
						intelligentDefaultToSelfDefined(start, end);
						break;

					default:
						intelligentDefaultToSelfDefined(start, end);
						break;
					}

					break;

				case FLIPFLOP:

					switch (sourceType) {

					case TWO_MX:
						intelligentTwoMxToFFStartXgreaterThanEndX(start, end);
						break;

					case FLIPFLOP:
						intelligentFFToFFStartXgreaterThanEndX(start, end);
						break;

					case NODE:
						intelligentNodeToFFStartXgreaterThanEndX(start, end);
						break;

					case SELFDEFINED:
						intelligentSelfDefinedToFFStartXgreaterThanEndX(start,
								end);
						break;

					default:
						intelligentDefaultToFFStartXgreaterThanEndX(start, end);
						break;
					}

					break;

				default:

					switch (sourceType) {

					case TWO_MX:
						intelligentTwoMxToDefaultStartXgreaterThanEndX(start,
								end);
						break;

					case FLIPFLOP:
						intelligentFFToFFStartXgreaterThanEndX(start, end);
						break;

					case NODE:
						intelligentNodeToFFStartXgreaterThanEndX(start, end);
						break;

					default:
						intelligentDefaultToDefaultStartXgreaterThanEndX(start,
								end);
						break;
					}
				}

				// sonst wird sie noch nicht intelligent gezeichnet
			} else {
				unIntelligentPathStartXgreaterThanEndX(start, end);
			}
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void unIntelligentDefaultToDefaultStartXSmallerThanEndX(
			Point2D start, Point2D end) {
		path.moveTo(start.getX(), start.getY());
		cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
		path.lineTo((start.getX() + end.getX()) / 2, start.getY());
		cornersOfPath.add(new Point2D.Double((start.getX() + end.getX()) / 2,
				start.getY()));
		path.lineTo((start.getX() + end.getX()) / 2, end.getY());
		cornersOfPath.add(new Point2D.Double((start.getX() + end.getX()) / 2,
				end.getY()));
		path.lineTo(end.getX(), end.getY());
		goBackDrawedPath(cornersOfPath);
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void unIntelligentPathStartXgreaterThanEndX(Point2D start,
			Point2D end) {
		path.moveTo(start.getX(), start.getY());
		cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
		path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
				start.getY());
		cornersOfPath.add(new Point2D.Double(start.getX()
				+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
		path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
				end.getY());
		cornersOfPath.add(new Point2D.Double(start.getX()
				+ UtilityConstants.CONNECTOR_MARGIN, end.getY()));
		path.lineTo(end.getX(), end.getY());
		goBackDrawedPath(cornersOfPath);
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentDefaultToTwoMxStartXSmallerThanEndX(Point2D start,
			Point2D end) {
		if (start.getY() < end.getY()) {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo(end.getX(), start.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), start.getY()));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			} else {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			}
		} else {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo((start.getX() + end.getX()) / 2, end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(
						(start.getX() + end.getX()) / 2, end.getY()
								- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo((start.getX() + end.getX()) / 2, start.getY());
				cornersOfPath.add(new Point2D.Double(
						(start.getX() + end.getX()) / 2, start.getY()));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			} else {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo((end.getX() + start.getX()) / 2, end.getY());
				cornersOfPath.add(new Point2D.Double(
						(end.getX() + start.getX()) / 2, end.getY()));
				path.lineTo((end.getX() + start.getX()) / 2, start.getY());
				cornersOfPath.add(new Point2D.Double(
						(end.getX() + start.getX()) / 2, start.getY()));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			}
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentDefaultToDefaultStartXLittleSmallerThanEndX(
			Point2D start, Point2D end) {
		if (target.getName().equals(Input.STD_A)
				|| target.getName().equals(Input.STD_B)) {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					(start.getY() + end.getY()) / 2);
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, (start.getY() + end
					.getY()) / 2));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					(start.getY() + end.getY()) / 2);
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, (start.getY() + end
					.getY()) / 2));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					end.getY());
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		} else if (target.getName().equals(Input.STD_A)) {
			if (end.getY() < start.getY()) {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY() + 1.7 * UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY() + 1.7
						* UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						end.getY() + 1.7 * UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, end.getY() + 1.7
						* UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			} else {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY() - 1.7 * UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY() - 1.7
						* UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						end.getY() - 1.7 * UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, end.getY() - 1.7
						* UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			}
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentDefaultToDefaultStartXgreaterThanEndX(
			Point2D start, Point2D end) {

		if (target.getName().equals(Input.STD_A)) {
			path.moveTo(end.getX(), end.getY());
			cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					end.getY());
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					end.getY() - UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()
					- UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					end.getY() - UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, end.getY()
					- UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX(), start.getY());
			goBackDrawedPath(cornersOfPath);
		} else if (target.getName().equals(Input.STD_B)) {
			path.moveTo(end.getX(), end.getY());
			cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					end.getY());
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					end.getY() + UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					end.getY() + UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, end.getY()
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX(), start.getY());
			goBackDrawedPath(cornersOfPath);
		} else if (target.getName().equals(Input.STD_A)) {
			if (end.getY() < start.getY()) {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY() + 1.7 * UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY() + 1.7
						* UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						end.getY() + 1.7 * UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, end.getY() + 1.7
						* UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			} else {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY() - 1.7 * UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY() - 1.7
						* UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						end.getY() - 1.7 * UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, end.getY() - 1.7
						* UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			}
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentDefaultToTwoMxStartXgreaterThanEndX(Point2D start,
			Point2D end) {
		if (start.getY() < end.getY()) {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						end.getY() - UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			} else {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						start.getY() + 1.6 * UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, start.getY() + 1.6
						* UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY() + 1.6 * UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY() + 1.6
						* UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			}
		} else {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						end.getY() - UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			} else {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY() + 1.6 * UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY() + 1.6
						* UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						start.getY() + 1.6 * UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, start.getY() + 1.6
						* UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);
			}
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentDefaultToFFStartXgreaterThanEndX(Point2D start,
			Point2D end) {
		path.moveTo(start.getX(), start.getY());
		cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
		path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
				start.getY());
		cornersOfPath.add(new Point2D.Double(start.getX()
				+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
		path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
				start.getY() + 1.6 * UtilityConstants.CONNECTOR_MARGIN);
		cornersOfPath.add(new Point2D.Double(start.getX()
				+ UtilityConstants.CONNECTOR_MARGIN, start.getY() + 1.6
				* UtilityConstants.CONNECTOR_MARGIN));
		path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
				start.getY() + 1.6 * UtilityConstants.CONNECTOR_MARGIN);
		cornersOfPath.add(new Point2D.Double(end.getX()
				- UtilityConstants.CONNECTOR_MARGIN, start.getY() + 1.6
				* UtilityConstants.CONNECTOR_MARGIN));
		path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN, end.getY());
		cornersOfPath.add(new Point2D.Double(end.getX()
				- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
		path.lineTo(end.getX(), end.getY());
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentTwoMxToTwoMxStartXSmallerThanEndX(Point2D start,
			Point2D end) {
		if (start.getY() < end.getY()) {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			} else {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo(start.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(start.getX(), end.getY()));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			}
		} else {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(start.getX(), start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo((start.getX() + end.getX()) / 2, start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(
						(start.getX() + end.getX()) / 2, start.getY()
								+ UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo((start.getX() + end.getX()) / 2, end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(
						(start.getX() + end.getX()) / 2, end.getY()
								- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);
			} else {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(start.getX(), start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						start.getY() + UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);
			}

		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentTwoMxToTwoMxStartXgreaterThanEndX(Point2D start,
			Point2D end) {
		if (start.getY() < end.getY()) {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			} else {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						start.getY() + UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX(), start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			}
		} else {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(start.getX(), start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo((start.getX() + end.getX()) / 2, start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(
						(start.getX() + end.getX()) / 2, start.getY()
								+ UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo((start.getX() + end.getX()) / 2, end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(
						(start.getX() + end.getX()) / 2, end.getY()
								- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);
			} else {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(start.getX(), start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						start.getY() + UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);

			}
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentTwoMxToDefaultStartXSmallerThanEndX(Point2D start,
			Point2D end) {
		if (start.getY() > end.getY()) {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX(), start.getY()
					+ UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo((end.getX() + start.getX()) / 2, start.getY()
					+ UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(
					(end.getX() + start.getX()) / 2, start.getY()
							+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo((end.getX() + start.getX()) / 2, end.getY());
			cornersOfPath.add(new Point2D.Double(
					(end.getX() + start.getX()) / 2, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		} else {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX(), end.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentTwoMxToDefaultStartXgreaterThanEndX(Point2D start,
			Point2D end) {
		path.moveTo(start.getX(), start.getY());
		cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
		path.lineTo(start.getX(), start.getY()
				+ UtilityConstants.CONNECTOR_MARGIN);
		cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()
				+ UtilityConstants.CONNECTOR_MARGIN));
		path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
				start.getY() + UtilityConstants.CONNECTOR_MARGIN);
		cornersOfPath.add(new Point2D.Double(end.getX()
				- UtilityConstants.CONNECTOR_MARGIN, start.getY()
				+ UtilityConstants.CONNECTOR_MARGIN));
		path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN, end.getY());
		cornersOfPath.add(new Point2D.Double(end.getX()
				- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
		path.lineTo(end.getX(), end.getY());
		goBackDrawedPath(cornersOfPath);
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentTwoMxToFFStartXgreaterThanEndX(Point2D start,
			Point2D end) {

		path.moveTo(start.getX(), start.getY());
		cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
		path.lineTo(start.getX(), start.getY()
				+ UtilityConstants.CONNECTOR_MARGIN);
		cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()
				+ UtilityConstants.CONNECTOR_MARGIN));
		path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
				start.getY() + UtilityConstants.CONNECTOR_MARGIN);
		cornersOfPath.add(new Point2D.Double(end.getX()
				- UtilityConstants.CONNECTOR_MARGIN, start.getY()
				+ UtilityConstants.CONNECTOR_MARGIN));
		path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN, end.getY());
		cornersOfPath.add(new Point2D.Double(end.getX()
				- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
		path.lineTo(end.getX(), end.getY());
		goBackDrawedPath(cornersOfPath);

	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentFFToTwoMxStartXSmallerThanEndX(Point2D start,
			Point2D end) {
		if (start.getY() < end.getY()) {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(end.getX(), start.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), start.getY()));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);
			} else {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo((start.getX() + end.getX()) / 2, start.getY());
				cornersOfPath.add(new Point2D.Double(
						(start.getX() + end.getX()) / 2, start.getY()));
				path.lineTo((start.getX() + end.getX()) / 2, end.getY());
				cornersOfPath.add(new Point2D.Double(
						(start.getX() + end.getX()) / 2, end.getY()));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);

			}
		} else {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo((start.getX() + end.getX()) / 2, start.getY());
				cornersOfPath.add(new Point2D.Double(
						(start.getX() + end.getX()) / 2, start.getY()));
				path.lineTo((start.getX() + end.getX()) / 2, end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(
						(start.getX() + end.getX()) / 2, end.getY()
								- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);

			} else {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo((start.getX() + end.getX()) / 2, start.getY());
				cornersOfPath.add(new Point2D.Double(
						(start.getX() + end.getX()) / 2, start.getY()));
				path.lineTo((start.getX() + end.getX()) / 2, end.getY());
				cornersOfPath.add(new Point2D.Double(
						(start.getX() + end.getX()) / 2, end.getY()));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);

			}
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentFFToTwoMxStartXgreaterThanEndX(Point2D start,
			Point2D end) {
		if (start.getY() < end.getY()) {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				if (source.getName().equals(Output.FF_Q)) {
					path.moveTo(start.getX(), start.getY());
					cornersOfPath.add(new Point2D.Double(start.getX(), start
							.getY()));
					path.lineTo(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY());
					cornersOfPath.add(new Point2D.Double(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
					path.lineTo(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
							- UtilityConstants.CONNECTOR_MARGIN);
					cornersOfPath.add(new Point2D.Double(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
							- UtilityConstants.CONNECTOR_MARGIN));
					path.lineTo(end.getX(), start.getY()
							- UtilityConstants.CONNECTOR_MARGIN);
					cornersOfPath.add(new Point2D.Double(end.getX(), start
							.getY() - UtilityConstants.CONNECTOR_MARGIN));
					path.lineTo(end.getX(), end.getY());
					goBackDrawedPath(cornersOfPath);
				} else {
					path.moveTo(start.getX(), start.getY());
					cornersOfPath.add(new Point2D.Double(start.getX(), start
							.getY()));
					path.lineTo(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY());
					cornersOfPath.add(new Point2D.Double(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
					path.lineTo(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
							+ 1.1 * UtilityConstants.CONNECTOR_MARGIN);
					cornersOfPath.add(new Point2D.Double(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
							+ 1.1 * UtilityConstants.CONNECTOR_MARGIN));
					path.lineTo(end.getX(), start.getY() + 1.1
							* UtilityConstants.CONNECTOR_MARGIN);
					cornersOfPath.add(new Point2D.Double(end.getX(), start
							.getY() + 1.1 * UtilityConstants.CONNECTOR_MARGIN));
					path.lineTo(end.getX(), end.getY());
					goBackDrawedPath(cornersOfPath);
				}
			} else {
				if (source.getName().equals(Output.FF_Q)) {
					path.moveTo(start.getX(), start.getY());
					cornersOfPath.add(new Point2D.Double(start.getX(), start
							.getY()));
					path.lineTo(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY());
					cornersOfPath.add(new Point2D.Double(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
					path.lineTo(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
							- UtilityConstants.CONNECTOR_MARGIN);
					cornersOfPath.add(new Point2D.Double(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
							- UtilityConstants.CONNECTOR_MARGIN));
					path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
							start.getY() - UtilityConstants.CONNECTOR_MARGIN);
					cornersOfPath.add(new Point2D.Double(end.getX()
							- UtilityConstants.CONNECTOR_MARGIN, start.getY()
							- UtilityConstants.CONNECTOR_MARGIN));
					path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
							end.getY());
					cornersOfPath.add(new Point2D.Double(end.getX()
							- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
					path.lineTo(end.getX(), end.getY());
					goBackDrawedPath(cornersOfPath);
				} else {
					path.moveTo(start.getX(), start.getY());
					cornersOfPath.add(new Point2D.Double(start.getX(), start
							.getY()));
					path.lineTo(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY());
					cornersOfPath.add(new Point2D.Double(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
					path.lineTo(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
							+ 1.1 * UtilityConstants.CONNECTOR_MARGIN);
					cornersOfPath.add(new Point2D.Double(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
							+ 1.1 * UtilityConstants.CONNECTOR_MARGIN));
					path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
							start.getY() + 1.1
									* UtilityConstants.CONNECTOR_MARGIN);
					cornersOfPath.add(new Point2D.Double(end.getX()
							- UtilityConstants.CONNECTOR_MARGIN, start.getY()
							+ 1.1 * UtilityConstants.CONNECTOR_MARGIN));
					path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
							end.getY());
					cornersOfPath.add(new Point2D.Double(end.getX()
							- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
					path.lineTo(end.getX(), end.getY());
					goBackDrawedPath(cornersOfPath);
				}
			}
		} else {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				path.moveTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				path.lineTo(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						end.getY() - UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(start.getX(), start.getY());
				goBackDrawedPath(cornersOfPath);
			} else {
				if (source.getName().equals(Output.FF_Q)) {
					path.moveTo(start.getX(), start.getY());
					cornersOfPath.add(new Point2D.Double(start.getX(), start
							.getY()));
					path.lineTo(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY());
					cornersOfPath.add(new Point2D.Double(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
					path.lineTo(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
							- UtilityConstants.CONNECTOR_MARGIN);
					cornersOfPath.add(new Point2D.Double(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
							- UtilityConstants.CONNECTOR_MARGIN));
					path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
							start.getY() - UtilityConstants.CONNECTOR_MARGIN);
					cornersOfPath.add(new Point2D.Double(end.getX()
							- UtilityConstants.CONNECTOR_MARGIN, start.getY()
							- UtilityConstants.CONNECTOR_MARGIN));
					path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
							end.getY());
					cornersOfPath.add(new Point2D.Double(end.getX()
							- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
					path.lineTo(end.getX(), end.getY());
					goBackDrawedPath(cornersOfPath);

				} else {
					path.moveTo(start.getX(), start.getY());
					cornersOfPath.add(new Point2D.Double(start.getX(), start
							.getY()));
					path.lineTo(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY());
					cornersOfPath.add(new Point2D.Double(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
					path.lineTo(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
							+ 1.1 * UtilityConstants.CONNECTOR_MARGIN);
					cornersOfPath.add(new Point2D.Double(start.getX()
							+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
							+ 1.1 * UtilityConstants.CONNECTOR_MARGIN));
					path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
							start.getY() + 1.1
									* UtilityConstants.CONNECTOR_MARGIN);
					cornersOfPath.add(new Point2D.Double(end.getX()
							- UtilityConstants.CONNECTOR_MARGIN, start.getY()
							+ 1.1 * UtilityConstants.CONNECTOR_MARGIN));
					path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
							end.getY());
					cornersOfPath.add(new Point2D.Double(end.getX()
							- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
					path.lineTo(end.getX(), end.getY());
					goBackDrawedPath(cornersOfPath);
				}
			}
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentFFToDefaultStartXSmallerThanEndX(Point2D start,
			Point2D end) {
		path.moveTo(start.getX(), start.getY());
		cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
		path.lineTo((start.getX() + end.getX()) / 2, start.getY());
		cornersOfPath.add(new Point2D.Double((start.getX() + end.getX()) / 2,
				start.getY()));
		path.lineTo((start.getX() + end.getX()) / 2, end.getY());
		cornersOfPath.add(new Point2D.Double((start.getX() + end.getX()) / 2,
				end.getY()));
		path.lineTo(end.getX(), end.getY());
		goBackDrawedPath(cornersOfPath);
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentFFToFFStartXgreaterThanEndX(Point2D start,
			Point2D end) {
		if (source.getName().equals(Output.FF_Q)) {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY() - UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
					- UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					start.getY() - UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, start.getY()
					- UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					end.getY());
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		} else {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY() + 1.1 * UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY() + 1.1
					* UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					start.getY() + 1.1 * UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, start.getY() + 1.1
					* UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					end.getY());
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentTwoMxToFFStartXSmallerEndX(Point2D start,
			Point2D end) {
		path.moveTo(start.getX(), start.getY());
		cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
		path.lineTo(start.getX(), start.getY()
				+ UtilityConstants.CONNECTOR_MARGIN);
		cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()
				+ UtilityConstants.CONNECTOR_MARGIN));
		path.lineTo((start.getX() + end.getX()) / 2, start.getY()
				+ UtilityConstants.CONNECTOR_MARGIN);
		cornersOfPath.add(new Point2D.Double((start.getX() + end.getX()) / 2,
				start.getY() + UtilityConstants.CONNECTOR_MARGIN));
		path.lineTo((start.getX() + end.getX()) / 2, end.getY());
		cornersOfPath.add(new Point2D.Double((start.getX() + end.getX()) / 2,
				end.getY()));
		path.lineTo(end.getX(), end.getY());
		goBackDrawedPath(cornersOfPath);
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentNodeToTwoMxStartXSmallerThanEndX(Point2D start,
			Point2D end) {
		if (end.getY() < start.getY()) {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(start.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);

			} else {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(start.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(start.getX(), end.getY()));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);
			}
		} else {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(end.getX(), start.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), start.getY()));
				path.lineTo(end.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()));
				goBackDrawedPath(cornersOfPath);

			} else {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(start.getX(), end.getY());
				cornersOfPath.add(new Point2D.Double(start.getX(), end.getY()));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);
			}
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentNodeToTwoMxStartXgreaterThanEndX(Point2D start,
			Point2D end) {
		if (end.getY() < start.getY()) {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(start.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);

			} else {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY() - UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						start.getY() - UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, start.getY()
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);
			}
		} else {
			if (target.getName().equals(Input.STD_A)
					|| target.getName().equals(Input.STD_B)) {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(end.getX(), start.getY());
				cornersOfPath.add(new Point2D.Double(end.getX(), start.getY()));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);

			} else {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY() + UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						start.getY() + UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, start.getY()
						+ UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(end.getX()
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);
			}
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligenteNodeToDefaultStartXSmallerThanEndX(Point2D start,
			Point2D end) {
		path.moveTo(start.getX(), start.getY());
		cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
		path.lineTo(start.getX(), end.getY());
		cornersOfPath.add(new Point2D.Double(start.getX(), end.getY()));
		path.lineTo(end.getX(), end.getY());
		goBackDrawedPath(cornersOfPath);
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentNodeToFFStartXgreaterThanEndX(Point2D start,
			Point2D end) {
		if (start.getY() >= end.getY()) {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY() - UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
					- UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					start.getY() - UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, start.getY()
					- UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					end.getY());
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		} else {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY() + UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					start.getY() + UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, start.getY()
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					end.getY());
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		}

	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentDefaultToSelfDefined(Point2D start, Point2D end) {
		LogicEditorElement lEE = target.getMySuperElement();
		double compX = lEE.getXCoord();
		double compY = lEE.getYCoord();
		int maxIO = Math.max(lEE.getInputs().size(), lEE.getOutputs().size());
		int height = maxIO * 20 + 20;

		if (start.getY() <= compY - 60) {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					(start.getY() + compY) / 2);
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN,
					(start.getY() + compY) / 2));
			path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN,
					(start.getY() + compY) / 2);
			cornersOfPath.add(new Point2D.Double(compX
					- UtilityConstants.CONNECTOR_MARGIN,
					(start.getY() + compY) / 2));
			path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, end.getY());
			cornersOfPath.add(new Point2D.Double(compX
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);

		} else if (start.getY() <= compY && start.getY() > compY - 60) {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY() - 1.7 * UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY() - 1.7
					* UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, start.getY()
					- 1.7 * UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(compX
					- UtilityConstants.CONNECTOR_MARGIN, start.getY() - 1.7
					* UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, end.getY());
			cornersOfPath.add(new Point2D.Double(compX
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		} else if (start.getY() > compY && start.getY() < compY + (height / 2)) {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN, compY
					- UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, compY
					- UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, compY
					- UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(compX
					- UtilityConstants.CONNECTOR_MARGIN, compY
					- UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, end.getY());
			cornersOfPath.add(new Point2D.Double(compX
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		} else {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN, compY
					+ height + UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, compY + height
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, compY
					+ height + UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(compX
					- UtilityConstants.CONNECTOR_MARGIN, compY + height
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, end.getY());
			cornersOfPath.add(new Point2D.Double(compX
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentTwoMxToSelfDefined(Point2D start, Point2D end) {
		LogicEditorElement lEE = target.getMySuperElement();
		double compX = lEE.getXCoord();
		double compY = lEE.getYCoord();
		int maxIO = Math.max(lEE.getInputs().size(), lEE.getOutputs().size());
		int height = maxIO * 20 + 20;

		if (start.getY() <= compY - 50) {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX(), start.getY()
					+ UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, start.getY()
					+ UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(compX
					- UtilityConstants.CONNECTOR_MARGIN, start.getY()
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, end.getY());
			cornersOfPath.add(new Point2D.Double(compX
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		} else if (start.getY() >= compY + height) {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX(), start.getY()
					+ UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, start.getY()
					+ UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(compX
					- UtilityConstants.CONNECTOR_MARGIN, start.getY()
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, end.getY());
			cornersOfPath.add(new Point2D.Double(compX
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		} else {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX(), compY + height
					+ UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX(), compY + height
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, compY
					+ height + UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(compX
					- UtilityConstants.CONNECTOR_MARGIN, compY + height
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, end.getY());
			cornersOfPath.add(new Point2D.Double(compX
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentFlipFlopToSelfDefined(Point2D start, Point2D end) {
		LogicEditorElement lEE = target.getMySuperElement();
		double compX = lEE.getXCoord();
		double compY = lEE.getYCoord();
		int maxIO = Math.max(lEE.getInputs().size(), lEE.getOutputs().size());
		int height = maxIO * 20 + 20;

		if (source.getName().equals(Output.FF_Q)) {
			if (start.getY() <= compY - 100) {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						compY - UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, compY
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, compY
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(compX
						- UtilityConstants.CONNECTOR_MARGIN, compY
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(compX
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);
			} else if (start.getY() > compY + height + 2
					* UtilityConstants.CONNECTOR_MARGIN) {
				path.moveTo(start.getX(), start.getY());
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						compY + height + UtilityConstants.CONNECTOR_MARGIN);
				path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, compY
						+ height + UtilityConstants.CONNECTOR_MARGIN);
				path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				path.lineTo(end.getX(), end.getY());

			} else {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(
						start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						Math.min(start.getY() - 1.3
								* UtilityConstants.CONNECTOR_MARGIN, compY
								- UtilityConstants.CONNECTOR_MARGIN));
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, Math.min(
						start.getY() - 1.3 * UtilityConstants.CONNECTOR_MARGIN,
						compY - UtilityConstants.CONNECTOR_MARGIN)));
				path.lineTo(
						compX - UtilityConstants.CONNECTOR_MARGIN,
						Math.min(start.getY() - 1.3
								* UtilityConstants.CONNECTOR_MARGIN, compY
								- UtilityConstants.CONNECTOR_MARGIN));
				cornersOfPath.add(new Point2D.Double(compX
						- UtilityConstants.CONNECTOR_MARGIN, Math.min(
						start.getY() - 1.3 * UtilityConstants.CONNECTOR_MARGIN,
						compY - UtilityConstants.CONNECTOR_MARGIN)));
				path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(compX
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);
			}
		} else {
			if (start.getY() <= compY - 2 * UtilityConstants.CONNECTOR_MARGIN) {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						compY - UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, compY
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN, compY
						- UtilityConstants.CONNECTOR_MARGIN);
				cornersOfPath.add(new Point2D.Double(compX
						- UtilityConstants.CONNECTOR_MARGIN, compY
						- UtilityConstants.CONNECTOR_MARGIN));
				path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(compX
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);
			} else {
				path.moveTo(start.getX(), start.getY());
				cornersOfPath
						.add(new Point2D.Double(start.getX(), start.getY()));
				path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						start.getY());
				cornersOfPath.add(new Point2D.Double(start.getX()
						+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
				path.lineTo(
						start.getX() + UtilityConstants.CONNECTOR_MARGIN,
						Math.max(compY + height
								+ UtilityConstants.CONNECTOR_MARGIN,
								start.getY() + 1.3
										* UtilityConstants.CONNECTOR_MARGIN));
				cornersOfPath
						.add(new Point2D.Double(start.getX()
								+ UtilityConstants.CONNECTOR_MARGIN, Math.max(
								compY + height
										+ UtilityConstants.CONNECTOR_MARGIN,
								start.getY() + 1.3
										* UtilityConstants.CONNECTOR_MARGIN)));
				path.lineTo(
						compX - UtilityConstants.CONNECTOR_MARGIN,
						Math.max(compY + height
								+ UtilityConstants.CONNECTOR_MARGIN,
								start.getY() + 1.3
										* UtilityConstants.CONNECTOR_MARGIN));
				cornersOfPath
						.add(new Point2D.Double(compX
								- UtilityConstants.CONNECTOR_MARGIN, Math.max(
								compY + height
										+ UtilityConstants.CONNECTOR_MARGIN,
								start.getY() + 1.3
										* UtilityConstants.CONNECTOR_MARGIN)));
				path.lineTo(compX - UtilityConstants.CONNECTOR_MARGIN,
						end.getY());
				cornersOfPath.add(new Point2D.Double(compX
						- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
				path.lineTo(end.getX(), end.getY());
				goBackDrawedPath(cornersOfPath);
			}
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentSelfDefinedToTwoMxStartXgreaterThandEndX(
			Point2D start, Point2D end) {
		LogicEditorElement lEE = source.getMySuperElement();
		double compY = lEE.getYCoord();
		int maxIO = Math.max(lEE.getInputs().size(), lEE.getOutputs().size());
		int height = maxIO * 20 + 20;

		if (compY + height <= end.getY() - 2
				* UtilityConstants.CONNECTOR_MARGIN) {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					end.getY() - UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, end.getY()
					- UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX(), end.getY()
					- UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(end.getX(), end.getY()
					- UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		} else {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN, Math
					.min(end.getY() - UtilityConstants.CONNECTOR_MARGIN, compY
							- UtilityConstants.CONNECTOR_MARGIN));
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, Math.min(end.getY()
					- UtilityConstants.CONNECTOR_MARGIN, compY
					- UtilityConstants.CONNECTOR_MARGIN)));
			path.lineTo(end.getX(), Math.min(end.getY()
					- UtilityConstants.CONNECTOR_MARGIN, compY
					- UtilityConstants.CONNECTOR_MARGIN));
			cornersOfPath.add(new Point2D.Double(end.getX(), Math.min(
					end.getY() - UtilityConstants.CONNECTOR_MARGIN, compY
							- UtilityConstants.CONNECTOR_MARGIN)));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		}
	}

	/**
	 * Hilfsmethode zum Zeichnen von Verbindungen (Name gibt Aufschluss ueber
	 * Funktion)
	 * 
	 * @param start
	 *            Startpunkt
	 * @param end
	 *            Endpunkt
	 */
	private void intelligentSelfDefinedToFFStartXgreaterThanEndX(Point2D start,
			Point2D end) {
		LogicEditorElement lEE = source.getMySuperElement();
		double compY = lEE.getYCoord();
		int maxIO = Math.max(lEE.getInputs().size(), lEE.getOutputs().size());
		int height = maxIO * 20 + 20;

		if (target.getMyElement().getYCoord() > compY + height + 2
				* UtilityConstants.CONNECTOR_MARGIN) {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN, compY
					+ height + UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, compY + height
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN, compY
					+ height + UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, compY + height
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					end.getY());
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		} else if (target.getMyElement().getYCoord() + 80 < compY - 2
				* UtilityConstants.CONNECTOR_MARGIN) {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN, compY
					- UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, compY
					- UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN, compY
					- UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, compY
					- UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					end.getY());
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		} else {
			path.moveTo(start.getX(), start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX(), start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN,
					start.getY());
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, start.getY()));
			path.lineTo(start.getX() + UtilityConstants.CONNECTOR_MARGIN, compY
					+ height + UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(start.getX()
					+ UtilityConstants.CONNECTOR_MARGIN, compY + height
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN, compY
					+ height + UtilityConstants.CONNECTOR_MARGIN);
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, compY + height
					+ UtilityConstants.CONNECTOR_MARGIN));
			path.lineTo(end.getX() - UtilityConstants.CONNECTOR_MARGIN,
					end.getY());
			cornersOfPath.add(new Point2D.Double(end.getX()
					- UtilityConstants.CONNECTOR_MARGIN, end.getY()));
			path.lineTo(end.getX(), end.getY());
			goBackDrawedPath(cornersOfPath);
		}

	}
}